function trArrServiceNextBusCreateUpdaters(arrivals_object, service_requests, updaters) {
	

	
	for (var avl_agency in service_requests) {
		var agency = avl_agency;
		if (agency == 'portland-sc') {
			agency = 'TriMet'; // awful hack, have to figure out how to get this from the data
		}
		updaters.push(new trArrNextBusUpdater(service_requests,arrivals_object,avl_agency,agency));
	}
	
}

function trArrNextBusUpdater(service_requests,arrivals_object,avl_agency,agency) {
	
	
	var updater = this;

	// every updater object needs to maintain a queue
	this.arrivals_queue = [];
	
	this.stop_translation = {};
	this.route_translation = {};
	

	
	var stop_tags = {};

	for (var i = 0; i < service_requests[avl_agency].length; i++) {

		for (var j = 0; j < service_requests[avl_agency][i].routes.length; j++) {
			
			// use GTFS ids unless avl_id defined for stop or route
			
			var route_id = service_requests[avl_agency][i].routes[j].route_id;
			if (service_requests[avl_agency][i].routes[j].route_id != undefined) {
				route_id = service_requests[avl_agency][i].routes[j].avl_id;
				route_id = route_id.replace(/\s+/g,'');
				this.route_translation[route_id] = service_requests[avl_agency][i].routes[j].route_id;
			}
			
			var stop_id = service_requests[avl_agency][i].stop_data.stop_id;
			if (service_requests[avl_agency][i].stop_data.avl_id != undefined) {
				stop_id = service_requests[avl_agency][i].stop_data.avl_id;
				stop_id = stop_id.replace(/\s+/g,'');
				this.stop_translation[stop_id] = service_requests[avl_agency][i].stop_data.stop_id;
			}
			
			var tag = route_id+"%257c"+stop_id;
			stop_tags[tag] = true; //hash so we can remove duplicates
		}

	}
	var tag_list = [];
	for (var tag in stop_tags) {
		tag_list.push("stops%3D"+tag);
	}


	var stop_string = tag_list.join('%26');
	var randomnumber=Math.floor(Math.random()*1000000)
	this.url = "http://query.yahooapis.com/v1/public/yql?q=%20SELECT%20*%20FROM%20xml%20WHERE%20url%3D'http%3A%2F%2Fwebservices.nextbus.com%2Fservice%2FpublicXMLFeed%3Fcommand%3DpredictionsForMultiStops%26a%3D"+avl_agency+"%26variation%3D"+randomnumber+"%26"+stop_string+"'&format=json";
	//alert(this.url);
	this.arrivals = function() {
		return this.arrivals_queue;
	}
	

	
	this.trArrRequestLoop = function() {
		
		jQuery.ajax({
		  url: updater.url,
		  dataType: 'jsonp',
		  cache: false,
		  success: function(data) {
		  	//debug_alert(data);
		  	var local_queue = [];
		  	var update_time = new Date().getTime();
		  	if (data.query != undefined && data.query.results != undefined && data.query.results.body != undefined && data.query.results.body.predictions != undefined && data.query.results.body.predictions.direction != undefined) {
		  		if (data.query.results.body.predictions.direction.prediction != undefined) {
		  			var predictions = data.query.results.body.predictions.direction.prediction;
		  			// need to deal with case where prediction may be an object (one element) rather than array
		  			if (!(predictions instanceof Array)) {
		  				predictions = [predictions];
		  			}
						for (var i = 0; i < predictions.length; i++){ 
							var arrival = predictions[i];
							//debug_alert(arrival);
							var entry = {};
							entry.arrivalTime = arrival.epochTime; // seconds since epoch for arrival
							entry.type = "estimated";
							entry.headsign = data.query.results.body.predictions.routeTitle+" "+data.query.results.body.predictions.direction.title;
							
							entry.stop_id = data.query.results.body.predictions.stopTag;
							if (updater.stop_translation[entry.stop_id] !=  undefined) {
								entry.stop_id = updater.stop_translation[entry.stop_id];
							}
							
							stop_data = trStopCache().stopData(agency,entry.stop_id);
							entry.stop_data = copyStopData(stop_data);
							
							entry.route_id = data.query.results.body.predictions.routeTag;
							if (updater.route_translation[entry.route_id] !=  undefined) {
								entry.route_id = updater.route_translation[entry.route_id];
							}
							
							if (stop_data != undefined && stop_data.routes != undefined) {
								for (var j = 0; j < stop_data.routes.length; j++){
									if (stop_data.routes[j].route_id == entry.route_id) {
										entry.route_data = stop_data.routes[j];
									}
								}
							}
							
							entry.alerts = ""; // need to figure this out later

							entry.agency = agency;
							entry.avl_agency = avl_agency;
							entry.last_updated = update_time;
							
							local_queue.push(entry);
						}
					}
				}
				
				
				// now copy to externally visble queue, making sure we're not in the middle of a query
				updater.arrivals_queue = local_queue;
				//jQuery('#arrivals_log_area').append("<PRE>"+dump(updater.arrivals_queue)+"</PRE>");
				
		  }
		});
	}
	

	
	updater.trArrRequestLoop(); // first time immediately
	setInterval(updater.trArrRequestLoop,60*1000); // once per minute
	

}

function copyStopData(data) {
	var out = {};
	for (var element in data) {
		// strip it down to just the GTFS elements
		if (element != 'routes' && element != 'geometry' && element != 'doc_type' && element.substring(0,1) != '_') {
			out[element] = data[element]
		}
	}
	return out;
}
			

